package Control;

import java.io.Serializable;

/**
 * <code>Version</code> class instances are versions.<p>
 * Version incapsulates code and version number.
 * @author hun10
 */
public class Version extends Command implements Comparable<Version>,
        Serializable {

    /**
     * Incapsulated code.
     */
    private int code;
    /**
     * Version number.
     */
    private int number;

    /**
     * Constructs valid version with given code.
     * @param code the code that should be incapsulated into the version
     * @throws Exception not a participant
     */
    public Version(int code) throws Exception {
        if (!swim.participates(selfID)) {
            throw new Exception("not a participant");
        }
        number = swim.nextNumber();
        this.code = code;
        Debug("created " + toString());
    }

    /**
     * Processes version.
     */
    @Override
    public synchronized void perform() {
        Debug("adding to SwimLines " + toString());
        swim.addVersion(this);
    }

    /**
     * Describes version.
     * @return version description
     */
    @Override
    public String toString() {
        return "version " + number + " with code " + code + " " + super.toString();
    }

    /**
     * Provides natural ordering in the storage set.<p>
     * The code field doesn't affect comparision.
     * @param o version that is being compared to this version
     * @return <ul>
     * <li>= 0, if versions are equall
     * <li>&gt; 0, if version is greater than <code>o</code>
     * <li>&lt; 0, if version is less than <code>o</code>
     * </ul>
     */
    public int compareTo(Version o) {
        if (number < o.number) {
            return -1;
        }
        if (number > o.number) {
            return 1;
        }
        return ID.compareTo(o.ID);
    }

    /**
     * Equals objects.<p>
     * The code field doesn't affect equality.
     * @param o object to be compared with version
     * @return objects equality
     */
    @Override
    public boolean equals(Object o) {
        if (number != ((Version) o).number) {
            return false;
        }
        return ID.equals(((Version) o).ID);
    }

    /**
     * Hashes version fields except the code field.
     * @return version hash
     */
    @Override
    public int hashCode() {
        int hash = 3;
        hash = 53 * hash + this.number;
        hash = 53 * hash + (this.ID != null ? this.ID.hashCode() : 0);
        return hash;
    }

    /**
     * Returns version participant ID.
     * @return participant ID
     */
    public String getID() {
        return ID;
    }

    /**
     * Returns version number.
     * @return version number
     */
    public int getNumber() {
        return number;
    }

    /**
     * Returns version code.
     * @return version code
     */
    public int getCode() {
        return code;
    }
}
